package com.cdks.wuxiu.api.service.mysql;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdks.wuxiu.api.component.constant.Constant;
import com.cdks.wuxiu.api.mapper.UserBaseInfoMapper;
import com.cdks.wuxiu.api.model.dto.UserAnswerStatisDTO;
import com.cdks.wuxiu.api.model.dto.UserInfoDTO;
import com.cdks.wuxiu.api.model.dto.UserListDTO;
import com.cdks.wuxiu.api.util.TimeUtils;
import com.cdks.wuxiu.entity.mysql.UserBaseInfo;
import java.util.List;
import java.util.Set;

import org.springframework.stereotype.Service;


/**
 * 用户基本信息表 服务实现类
 */
@Service
public class UserBaseInfoServiceImpl extends ServiceImpl<UserBaseInfoMapper, UserBaseInfo> implements UserBaseInfoService {
    @Override
    public UserInfoDTO getInfoByIdWithStatis(long userId) {
        return baseMapper.getInfoWithStatis(userId);
    }

    @Override
    public UserInfoDTO getInfoByIdWithBalance(long userId, long expire) {
        return baseMapper.getInfoWithBalance(userId, expire);
    }

    @Override
    public UserInfoDTO getInfoByIdWithFocus(long userId, long fansId) {
        return baseMapper.getInfoWithFocus(userId, fansId);
    }

    @Override
    public UserBaseInfo getInfoById(long userId) {
        QueryWrapper<UserBaseInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getUserId, userId);      

        return baseMapper.selectOne(wrapper);
    }

    @Override
    public UserBaseInfo getInfoByPhone(String phone) {
        QueryWrapper<UserBaseInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getPhone, phone)
                        .between(UserBaseInfo::getBranch, 300, 399)
                        .orderByDesc(UserBaseInfo::getUserId);

        return baseMapper.selectOne(wrapper.last("LIMIT 1"));
    }

    @Override
    public UserBaseInfo getInviterInfo(long userId) {
        return baseMapper.getInviterInfo(userId);
    }

    @Override
    public int deleteUserInfo(UserBaseInfo userInfo) {
        userInfo.setStatus(Constant.ACCOUNT_STATUS_DELETED);

        updateById(userInfo);
        
        return 0;
    }  

    @Override
    public int setInviteStatus(UserBaseInfo userInfo, int status) {
        if (userInfo.getBindStatus() >= status) {
            return -1;
        }

        userInfo.setBindStatus(status);
        super.updateById(userInfo);

        return 0;
    }

    @Override
    public int autoInviter(UserBaseInfo userInfo, long inviter) {
        userInfo.setBindStatus(Constant.INVITE_STATUS_PRBIND);
        userInfo.setBindInviter(inviter);
    
        UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getUserId, userInfo.getUserId())
                        .eq(UserBaseInfo::getBindStatus, Constant.INVITE_STATUS_UNBIND);

        int ret  = baseMapper.update(userInfo, wrapper);
        if (ret == 1)
        {
            return 0;
        }

        return -1;
    }

    @Override
    public int bindInviter(UserBaseInfo userInfo, long inviter) {
        userInfo.setBindStatus(Constant.INVITE_STATUS_BINDED);
        userInfo.setBindInviter(inviter);
    
        UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getUserId, userInfo.getUserId())
                        .lt(UserBaseInfo::getBindStatus, Constant.INVITE_STATUS_BINDED);

        int ret  = baseMapper.update(userInfo, wrapper);
        if (ret == 1)
        {
            return 0;
        }

        return -1;
    }

    @Override
    public int updateInviter(UserBaseInfo userInfo, long inviter) {
        userInfo.setBindStatus(Constant.INVITE_STATUS_REFUSE);
        userInfo.setBindInviter(inviter);

        UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getUserId, userInfo.getUserId())
                        .ne(UserBaseInfo::getBindStatus, Constant.INVITE_STATUS_REFUSE)
                        .ne(UserBaseInfo::getBindInviter, inviter)
                        .gt(UserBaseInfo::getCreateTime, TimeUtils.getTimeSecond() - Constant.TIME_VALUE_24_HOURS);

        int ret  = baseMapper.update(userInfo, wrapper);
        if (ret == 1)
        {
            return 0;
        }

        return -1;
    }

    @Override
    public int updateListenerInfo(UserBaseInfo userInfo, UserAnswerStatisDTO statis) {
        int answerRate  = statis.getAnswerRate();
        int callAvgTime  = statis.getCallAvgTime();
        int authLevel   = userInfo.getAuthLevel();

        if (answerRate > 90)
        {
            if (callAvgTime > 1200)
            {
                authLevel  = Constant.AUTH_LEVEL_GOLD;
            }
            else if (callAvgTime > 600)
            {
                authLevel  = Constant.AUTH_LEVEL_SILVER;
            }
            else if (callAvgTime > 300)
            {
                authLevel  = Constant.AUTH_LEVEL_BRASS;
            }
            else
            {
                authLevel  = Constant.AUTH_LEVEL_STUDY;
            }
        }
        else if (answerRate > 80)
        {
            if (callAvgTime > 2400)
            {
                authLevel  = Constant.AUTH_LEVEL_GOLD;
            }
            else if (callAvgTime > 1200)
            {
                authLevel  = Constant.AUTH_LEVEL_SILVER;
            }
            else if (callAvgTime > 600)
            {
                authLevel  = Constant.AUTH_LEVEL_BRASS;
            }
            else
            {
                authLevel  = Constant.AUTH_LEVEL_STUDY;
            }
        }
        else if (answerRate > 70)
        {
            if (callAvgTime > 2400)
            {
                authLevel  = Constant.AUTH_LEVEL_SILVER;
            }
            else if (callAvgTime > 1200)
            {
                authLevel  = Constant.AUTH_LEVEL_BRASS;
            }
            else
            {
                authLevel  = Constant.AUTH_LEVEL_STUDY;
            }
        }
        else if (answerRate > 60)
        {
            if (callAvgTime > 2400)
            {
                authLevel  = Constant.AUTH_LEVEL_BRASS;
            }
            else
            {
                authLevel  = Constant.AUTH_LEVEL_STUDY;
            }
        }
        else if ((statis.getAnswerCnt() == 0) && (statis.getCallInCnt() >= 3))
        {
            userInfo.setAuthLevel(Constant.AUTH_LEVEL_NONE);
            userInfo.setAuthRole(Constant.AUTH_ROLE_TALKER);

            cancelAuth(userInfo.getUserId());

            return 0;
        }
        else
        {
            authLevel  = Constant.AUTH_LEVEL_STUDY;
        }

        //更新数据
        if ((answerRate != userInfo.getAnswerRate()) || (authLevel != userInfo.getAuthLevel()))
        {
            int maxPrice  = (authLevel + 1) * 100;            
            if (userInfo.getAudioPrice() > maxPrice)
            {
                userInfo.setAudioPrice(maxPrice);
            }

            userInfo.setAnswerRate(answerRate);
            userInfo.setAuthLevel(authLevel);

            UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
            wrapper.lambda().eq(UserBaseInfo::getUserId, userInfo.getUserId())
                            .set(UserBaseInfo::getAuthLevel, userInfo.getAuthLevel())
                            .set(UserBaseInfo::getAnswerRate, userInfo.getAnswerRate())
                            .set(UserBaseInfo::getAudioPrice, userInfo.getAudioPrice());

            int ret = baseMapper.update(null, wrapper);
            if (ret != 1)
            {
                log.error("update listener info failed: " + userInfo + ", ret = " + ret);

                return -1;
            }
        }

        return 0;
    }

    @Override
    public List<UserListDTO> getList(long self, int sex, int role, int userType, int type, int page) {
        return baseMapper.getUserList(page * Constant.LIST_PAGE_SIZE, Constant.LIST_PAGE_SIZE, self, sex, role, userType);
    }

    @Override
    public List<UserBaseInfo> getRandCallList(long selfId, int sex) {
        QueryWrapper<UserBaseInfo> wrapper;
        
        wrapper  = new QueryWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getSex, sex)
                        .eq(UserBaseInfo::getStatus, Constant.ACCOUNT_STATUS_NORMAL)
                        .lt(UserBaseInfo::getType, Constant.ACCOUNT_TYPE_PLAT)
                        .gt(UserBaseInfo::getAuthLevel, Constant.AUTH_LEVEL_NONE)
                        .ne(UserBaseInfo::getUserId, selfId);

        return baseMapper.selectList(wrapper.last("ORDER BY RAND() LIMIT " + Constant.LIST_PAGE_SIZE));
    }

    @Override
    public List<UserBaseInfo> getKefuList() {
        QueryWrapper<UserBaseInfo> wrapper;
        
        wrapper  = new QueryWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getStatus, Constant.ACCOUNT_STATUS_NORMAL)
                        .eq(UserBaseInfo::getType, Constant.ACCOUNT_TYPE_KEFU);

        return baseMapper.selectList(wrapper);        
    }

    @Override
    public int updateStatus(long userId, int status) {
        return baseMapper.updateStatus(userId, status); 
    }

    @Override
    public int updateOnlineStatus(long userId, int status) {
        return baseMapper.updateOnlineStatus(userId, status); 
    }

    @Override
    public int updateOnlineStatus(long userId, int oldStatus, int newStatus) {
        UserBaseInfo info  = new UserBaseInfo();
        info.setOnlineStatus(newStatus);
        
        UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getOnlineStatus, oldStatus)
                        .eq(UserBaseInfo::getUserId, userId);

        return baseMapper.update(info, wrapper);
    }

    @Override
    public int updateOnlineStatus(Set<String> ids, int oldStatus, int newStatus) {
        UserBaseInfo info  = new UserBaseInfo();
        info.setOnlineStatus(newStatus);
        
        UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getOnlineStatus, oldStatus)
                        .in(UserBaseInfo::getUserId, ids);

        return baseMapper.update(info, wrapper);
    }

    @Override
    public int cancelAuth(long userId) {
        UpdateWrapper<UserBaseInfo> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(UserBaseInfo::getUserId, userId)
                        .set(UserBaseInfo::getAuthLevel, 0)
                        .set(UserBaseInfo::getAuthRole, 0)
                        .set(UserBaseInfo::getAudioPrice, 0)
                        .set(UserBaseInfo::getTextPrice, 0)
                        .set(UserBaseInfo::getUserScore, 0);

        return baseMapper.update(null, wrapper);
    }
}
